package com.springcloud.eurekaconsumer.controller;


import com.springcloud.eurekaconsumer.interfaces.IProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

import java.util.concurrent.ExecutionException;


@RestController
@RequestMapping("consumer")
public class ConsumerController {

    //实现消费者负载均衡 调用server

    /**
     * 因为启动类有注解，所以这里就可以注入 restTemplate这个类，并且使用
     */
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private IProviderService providerService;
    @HystrixCommand(fallbackMethod = "serviceFallback")

   /**
     * 血的教训：
     *  访问消费者接口，消费者内部访问提供者，会报错
     *  原因是服务器名称不能用“_”,可以用“-”
     */

    @RequestMapping("hello")
    public String hello(){

        //假设这个消费者，需要调用生产者提供的服务接口
        //负载均衡的组件
        // 服务列表+负载均衡算法
//        ResponseEntity<String> forEntity = restTemplate.getForEntity("http://euraka-provider/provider/hello",String.class);
//        return forEntity.getBody();//可以动态调用两个服务器的端口

        return providerService.hello();

    }

    /**
     * 1.熔断机制的调用场景：
     *  一旦依赖的服务出现了问题，达到一定的阈值，
     *  就可以触发这个机制来包含沃恩的当前的服务不hi拖垮
     *
     *  还原场景的方法，把"消费者"之外的 都干掉，再来访问就能实现“熔断机制”，
     *  熔断机制是为了并发量太高，造成服务器瘫痪，服务器宕机后就不再接受请求，给服务端减压
     *
     * 2.服务降级：在高并发的场景下，取消一些非核心业务，将更多资源留给核心业务，保证核心业务正常运行
     */
    public String serviceFallback(){
        return "sorry,douguale!";
    }

    /**
     * @LoadBalanced原理说明
     *  RestTemplate本身是Spring-web项目的一个REST客户端，提供了我们调用HTTP的能力
     *  RestTemplate本身不具备负载均衡的能力，也跟SpreingClound没关系
     *  加入@LoadBalanced注解后，Spring容器在启动时，会为这些修饰了注解的RestTemplat添加拦截器
     *  拦截器使用loadBalancerClient来处理请求，loadBalancerClient就是Spring封装的负载均衡客户端
     *  通过这样的间接处理，就让RestTemplate具备了负载均衡的能力
     *
     *  Nginx是服务器端负载均衡，负载均衡的策略算法是在服务器端实现的
     *  Ribbon是在客户端负载均衡，负载均衡算法是由调用者本身维护的
     */

/**
 * 1.Ribbon,实现负载均衡服务器，需要包含两个部分信息
 * 1）.要维护每个服务器的IP和端口信息
 * 2).根据特定逻辑选择某个服务器
 *
 * 2.内部包含3个部分
 * 1）.Rule（算法）：一个逻辑组件，决定从服务器列表返回哪个服务器实例
 * 2）.评：该组件使用定时器来确保服务器网络可以连接
 * 3）.ServerList：服务器列表
 *
 * 3.使用
 * 1）.为上述的provider工程，编写controller，提供服务
 * 2）.为上述的consumer工程，编写contoller，内部调用provider开放的接口
 *     引入依赖包：
 *     具体调用的方案：
 *     1）在启动类，注册bean（RestTemplate）
 *        @Bean
 *        @LoadBalanced
 *        public RestTemplate getRestTemplate(){
 *            return new RestTemplate();
 *        }
 *     2)在controller中，注入RestTemplate
 *        @RestController
 *
 */

/**
 * Feign,REST客户端
 *
 * 1.什么是Feign
 *      1）Feign目的是简化对WebService客户端的开发，作用类似之前的CXF
 *      2）Feign可以使用注解来修饰接口，被修饰的接口将具备访问webService的能力
 *      3）Feign跟Eureka、Ribbon集成后，就具备了负载均衡的能力
 *
 * 2.使用：
 *      1）引入坐标：
 *          依赖
 *      2）启动类，添加注解 @EnableFeignClients
 *      3) 在消费者端，自定义接口 @FeignClient（Value = "eureka-provider"）
 *      4) controller注入service，实现服务的调用
 */


/**
 * 断路器，Hystrix--SpringCloud的保护机制，也称熔断机制
 *
 * 什么是hystrix
 *      1.是Netflix下的一个Java库，通过添加阈值及容错的逻辑，
 *      来帮助我们控制分布式系统间组件的交互
 *      2.通过隔离服务间的访问点，停止他们之间的级联故障，
 *      提供可回退操作来实现容错
 *      3.条件：当对特定的服务的调用的不可用达到一个阈值（Hystrix是5秒20次）
 *      断路器将会被打开
 *      4.在SpringCloud中使用：
 *      1）为消费者，引入依赖
 *      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
 *      2）为启动类，太你家注解：@EnableCircuitBreaker
 *      3）在消费者的controller中，加上熔断处理方法
 */

/**
 * 集群网关 Zuui：
 * 1.Zuui为我们的服务接口，提供了一个统一的网关，将集群的服务都隐藏在网关后面
 *   客户端只需关注网关的配置信息
 *   SpringCloud也无须暴露过多的服务，保证了安全性
 *
 * 2.有哪些功能：
 *   代理、过滤、路由
 *   传统的代理层技术有：Nginx、Apache
 *   Zuui默认和Ribbon结合实现了负载均衡的功能
 *
 * 3.路由功能：
 *   1）创建路由工程：springcloud_zuui
 *      依赖
 *   2）yml配置
 */

/**
 * SpringCloud Config,统一配置中心
 */
}

